package com.vanke.devops.domain.manager.influxdb.impl;

import com.google.common.collect.Lists;
import com.vanke.core.util.CollectionUtil;
import com.vanke.core.util.JsonUtil;
import com.vanke.core.util.StringUtil;
import com.vanke.devops.domain.manager.influxdb.InfluxDbManager;
import com.vanke.devops.domain.manager.influxdb.InfluxDbQuerySql;
import com.vanke.devops.domain.manager.influxdb.bean.InfluxDbNode;
import com.vanke.devops.domain.properties.InfluxDbProperties;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;

/**
 * @author 陈景阳
 * @since 2018/6/9
 */
@Component
@EnableConfigurationProperties(InfluxDbProperties.class)
public class InfluxDbManagerImpl implements InfluxDbManager{

    @Autowired
    private InfluxDB influxDB;

    @Autowired
    private InfluxDbProperties properties;

    private List<Double> getValue(QueryResult queryResult){
        List<QueryResult.Series> seriesList = Lists.newArrayList();
        List<QueryResult.Result> resultList = queryResult.getResults();
        for(QueryResult.Result result : resultList){
            if(CollectionUtil.isEmpty(result.getSeries())){
                return Lists.newArrayList();
            }
            seriesList.addAll(result.getSeries());
        }
        List<Object> objectList = Lists.newArrayList();
        for(QueryResult.Series series : seriesList){
            objectList.addAll(series.getValues());
        }
        List<Double> doubleList = Lists.newArrayList();
        for(Object o : objectList){
            List v = (ArrayList)o;
            if(v.size() == 2 && v.get(1) != null){
                doubleList.add((double)v.get(1));
            }
        }
        return doubleList;
    }

    private double getAvg(List<Double> value){
        if(CollectionUtil.isEmpty(value)){
            return 0;
        }
        OptionalDouble optionalDouble =value.stream().mapToDouble(Double::doubleValue).average();
        return optionalDouble.getAsDouble();
    }

    @Override
    public InfluxDbNode queryNode(String hostname) {
        InfluxDbNode influxDbNode = new InfluxDbNode();
        if(StringUtil.isEmpty(hostname)){
            return influxDbNode;
        }
        Query queryCpu = new Query(String.format(InfluxDbQuerySql.CPU_SQL,hostname),properties.getDatabase());
        QueryResult queryCpuResult = influxDB.query(queryCpu);
        double cpu = this.getAvg(this.getValue(queryCpuResult));
        influxDbNode.setCpu(cpu);

        Query queryMem = new Query(String.format(InfluxDbQuerySql.MEM_SQL,hostname),properties.getDatabase());
        QueryResult queryMemResult = influxDB.query(queryMem);
        double mem = this.getAvg(this.getValue(queryMemResult));
        influxDbNode.setMem(mem);

        Query queryDisk = new Query(String.format(InfluxDbQuerySql.DISK_SQL,hostname),properties.getDatabase());
        QueryResult queryDiskResult = influxDB.query(queryDisk);
        double disk = this.getAvg(this.getValue(queryDiskResult));
        influxDbNode.setDisk(disk);
        return influxDbNode;
    }

    @Override
    public String version() {
        return influxDB.version();
    }
}
